package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"io"
	"net/http"
)

//Animal 动物
type Animal struct {
	Id     int    `json:"Id"  xorm:"int64 pk 'Id'" form:"Id" binding:"required"` // Id
	Name   string `json:"name"  xorm:"varchar(20) notnull 'Name'" form:"Name"`   // 名字
	Age    int    `json:"age"  xorm:"int null 'Age'" form:"Age"`                 // 年龄
	Sex    int    `json:"sex"  xorm:"int null 'sex'" form:"Sex"`                 // 性别
	Weight int    `json:"weight"  xorm:"int null 'Weight'" form:"Weight"`        // 体重
}

func ModifyAnimal(c *gin.Context) {
	data, err := getPostData(c)
	if err != nil {
		c.String(http.StatusBadRequest, err.Error())
		return
	}
	rows, err2 := db.Update(data, Animal{Id: data.Id})
	if err2 != nil {
		fmt.Println(err2)
		c.String(http.StatusBadRequest, err2.Error())
		return
	}
	c.String(http.StatusOK, "update rows:%d", rows)
}

func DelAnimal(c *gin.Context) {
	req := Animal{}
	err := c.ShouldBind(&req)
	if err != nil {
		fmt.Println(err)
		c.String(http.StatusBadRequest, err.Error())
		return
	}
	rows, err2 := db.Delete(req)
	if err2 != nil {
		fmt.Println(err2)
		c.String(http.StatusBadRequest, "delete error:%v", err2.Error())
		return
	}
	c.String(http.StatusOK, "delete rows:%d", rows)
}

func AddAnimal(c *gin.Context) {
	fmt.Println("postForm, id:", c.Request.FormValue("Id"))
	data, err := getPostData(c)
	if err != nil {
		c.String(http.StatusBadRequest, err.Error())
		return
	}
	_, err = db.InsertOne(data)
	if err != nil {
		fmt.Println(err)
		c.String(http.StatusBadRequest, err.Error())
		return
	}
	c.JSON(http.StatusOK, &data)
}

func GetAnimal(c *gin.Context) {
	fmt.Println("params:", c.Params)
	fmt.Println("Query(id)", c.Query("Id"))
	req := Animal{}
	_ = c.ShouldBind(&req)
	fmt.Printf("get animal, bind param\n%+v\n", req)
	sData := make([]Animal, 0)
	err := db.Find(&sData, req)
	if err != nil {
		fmt.Println(err)
		c.String(http.StatusBadRequest, err.Error())
		return
	}
	c.JSON(http.StatusOK, &sData)
}

func getPostData(c *gin.Context) (Animal, error) {
	// check body type
	ct := c.Request.Header.Get("Content-Type")
	if ct != "application/json" {
		err := fmt.Errorf("body only support application/json")
		return Animal{}, err
	}

	// read body
	buf, _ := io.ReadAll(c.Request.Body)
	req := Animal{}
	err := json.Unmarshal(buf, &req)
	if err != nil {
		return Animal{}, err
	}

	fmt.Println("animal param:\n", string(buf))
	return req, nil
}
